View Javadoc
1 /* 2 * Title: S/MIME Project 3 * Description: S/MIME email sending capabilities 4 * @Author Vladan Obradovic 5 * @Version 2.0.1 6 */ 7 8 package org.webdocwf.util.smime.smime; 9 10 11 import org.webdocwf.util.smime.exception.SMIMEException; 12 import org.webdocwf.util.smime.exception.ErrorStorage; 13 import org.webdocwf.util.smime.activation.CMSEnvelopedDataSource; 14 import org.webdocwf.util.smime.activation.StreamDataSource; 15 import org.webdocwf.util.smime.mail.MultipartGenerator; 16 import org.webdocwf.util.smime.util.MimeAssist; 17 import org.webdocwf.util.smime.util.ConvertAssist; 18 import javax.mail.internet.HeadersUtil; 19 import javax.mail.Session; 20 import javax.mail.Message; 21 import javax.mail.Multipart; 22 import javax.mail.Transport; 23 import javax.mail.MessagingException; 24 import javax.mail.internet.MimeMessage; 25 import javax.mail.internet.MimeBodyPart; 26 import javax.mail.internet.MimeMultipart; 27 import javax.mail.internet.InternetAddress; 28 import javax.activation.DataHandler; 29 import javax.activation.FileDataSource; 30 import javax.activation.MimetypesFileTypeMap; 31 import java.util.Vector; 32 import java.util.Properties; 33 import java.util.SimpleTimeZone; 34 import java.util.GregorianCalendar; 35 import java.io.File; 36 import java.io.FileInputStream; 37 import java.io.InputStream; 38 import java.io.ByteArrayInputStream; 39 import java.security.Security; 40 import java.security.cert.X509Certificate; 41 import java.security.cert.CertificateFactory; 42 import sun.security.provider.Sun; 43 import org.bouncycastle.jce.provider.BouncyCastleProvider; 44 45 46 /*** 47 * EnvelopedSMIME class is used for creating and sending encrypted S/MIME 48 * message.<BR> 49 * <BR> 50 * Email message is in general composed of the content of the message and of one or 51 * more attachments. The content is visible part of the message, and attacments are 52 * mostly files or other binary data, which are not visible parts of message and 53 * which are used by email as a transport medium. In this implementation content 54 * can be represented in two different forms: <BR> 55 * <BR> 56 * <UL><LI> 57 * text/plain (only text withouth any formating) or 58 * </LI> <LI> 59 * text/html (html coded view of message) 60 * </LI></UL> 61 * Also, content can be absent, but than at least one attachment must be added. 62 * Content can be set on few manners. For text/plain type it can be done in time 63 * of construction with constructor designed special for creation of text/plain 64 * messages. Also, text content can be created by any of setContent() methods, 65 * if construction of object was done by other constructor which create object 66 * with empty content. Construction with other constructor offers a few different 67 * posibilities for importing content data (File, InputStream, String) by using 68 * appropriate setContent() method. If method with four parameters is used, 3rd 69 * ant 4th parameters are not in use for text/plain message and could be set 70 * null. For setting text/html content, construction of object should be done 71 * only by second mentioned constructor, which creates object with empty content. 72 * Content should be populated by html code with setContent() method. 3rd 73 * parameter is used for resolving relative addresses of resources in html 74 * code (images, movies...) and 4th parameter serves as data source for resources 75 * that are on special way addressed in html code. Also, there is a setContent() 76 * method which doesn't care about resources and which creates message content 77 * withouth them. For more information refer to setContent() methods.<BR> 78 * <BR> 79 * Message can contain any number of attachments. Also, message can 80 * be wihouth any attachment, but then content must be present. Every attachment 81 * should be added by performing single addAttachment() method. Attachments 82 * can be added from file or from InputStream. Mime-type which corresponds to 83 * particular attachment is obtained according to extension of file name 84 * (virtual or real file name) passed to addAttachment() method. File mime.types 85 * in META_INF directory contains list of mime-types and corresponding extensions 86 * which are used in determination of mime-type. File can be changed to satisfy 87 * secific requrements. For more information refer to addAttachmenttent() 88 * method.<BR> 89 * <BR> 90 * Encryption of message is performed by symmetric encryption with random 91 * generated symmetric key. This key is then encrypted by assymetric encryption 92 * with a recipient's public key, and sent together with encrypted message to 93 * recipient in CMS (Cryptographic Message Syntax) enveloped object. For all 94 * recipients of the message (if there is more than one) operation of encrypting 95 * symmetric key must be performed with his corresponding public key (from .cer 96 * file). Encryption can be performed by following algorithms and corresponding 97 * key sizes:<BR> 98 * <BR> 99 * RC2_CBC, 40 bits (default encryption)<BR> 100 * RC2_CBC, 64 bits<BR> 101 * RC2_CBC, 128 bits<BR> 102 * DES, 56 bits<BR> 103 * DES_EDE3_CBC, 128 bits<BR> 104 * DES_EDE3_CBC, 192 bits<BR> 105 * <BR> 106 * As a asymmetric algorithm, RSA algorithm is used.<BR> 107 * <BR> 108 */ 109 public class EnvelopedSMIME { 110 111 /*** 112 * Container for MIME message 113 */ 114 private MimeMessage message; 115 116 /*** 117 * Storage for .cer files coresponding to appropriate enveloping session 118 */ 119 private Vector certArray = new Vector(0, 1); 120 121 /*** 122 * Storage for MIME bodyparts 123 */ 124 private Vector bodyPartArray = new Vector(0, 1); 125 126 /*** 127 * Indication that at least one recipient must be TO (others may be CC or BCC) 128 */ 129 private boolean indicatorTo = false; 130 131 /*** 132 * Indicator of the presence of plain text content 133 */ 134 private boolean textContentPresence = false; 135 136 /*** 137 * Initializes the JavaMail session for SMTP and the MimeMessage for encryption. 138 * Dynamically loads the BC and SUN provider necessary for encryption. This 139 * constructor is used for creating message with text/plain content. For creating 140 * html formated content (text/html), other constructor should be used in 141 * combination with one of setContent methods. Note that after using this 142 * constructor setContent method can be used only if "content" argument of 143 * constructor was given as null, otherwise setContent method can't be used 144 * because content is already set as text/plain. 145 * @param smtpHost name of SMTP host used for sending email 146 * @param fromAddress email address of sender (FROM field in email header) 147 * @param subject subject of email (SUBJECT field in email header) 148 * @param content text/plain content of email message 149 * @exception SMIMEException if smtpHost or fromAddress parameters are null. 150 * Also, it can be caused by non SMIMEException which is MessagingException. 151 */ 152 public EnvelopedSMIME(String smtpHost, String fromAddress, String subject, 153 String content) throws SMIMEException { 154 try { 155 Security.addProvider(new BouncyCastleProvider()); // Dynamic loading the BC provider 156 Security.addProvider(new Sun()); // Dynamic loading the SUN provider necessary for SHA1withRSA 157 158 if (smtpHost == null | fromAddress == null) 159 throw new SMIMEException(this, 1041); 160 Properties sesProp = new Properties(); 161 162 sesProp.setProperty("mail.smtp.host", smtpHost); 163 Session ses = Session.getInstance(sesProp); 164 165 message = new MimeMessage(ses); 166 InternetAddress from = new InternetAddress(fromAddress); 167 168 message.setFrom(from); 169 if (subject != null) 170 message.setSubject(subject); 171 if (content != null) { 172 MimeBodyPart mbp = new MimeBodyPart(); 173 174 mbp.setText(content); 175 bodyPartArray.addElement(mbp); 176 textContentPresence = true; 177 } 178 } catch (Exception e) { 179 throw SMIMEException.getInstance(this, e, "constructor"); 180 } 181 } 182 183 /*** 184 * Initializes the JavaMail session for SMTP and the MimeMessage for encryption. 185 * Dynamically loads the BC and SUN provider necessary for encryption. This 186 * constructor does not create content of message and it can be set later with 187 * one of setContent methods. Also, message can be left withouth content, but 188 * then at least one attachement must be added. 189 * @param smtpHost name of SMTP host used for sending email 190 * @param fromAddress email address of sender (FROM field in email header) 191 * @param subject subject of email (SUBJECT field in email header) 192 * @exception SMIMEException if smtpHost or fromAddress parameters are null. 193 * Also, it can be caused by non SMIMEException which is MessagingException. 194 */ 195 public EnvelopedSMIME(String smtpHost, String fromAddress, String subject) 196 throws SMIMEException { 197 this(smtpHost, fromAddress, subject, null); 198 } 199 200 /*** 201 * Sets message content. Message content can be given in two differrent forms: 202 * text and html code. If content is type of text, parameter "type" should be 203 * "text/plain" and other two parameters are not in use (should be set null). 204 * If content is type of html code, parameter "type" should be set as "text/html", 205 * otherwise (if it is set as "text/plain") html code is processed as a plain 206 * text. This method can be performed only once.<BR> 207 * <BR> 208 * In case of html content, it is essential to (on appropriate way) associate some 209 * attributes of particular elements in html code ("background" or "src" atributes) 210 * with corresponding ressources (URL-s, relative file addresses or byte array 211 * streams). This resources should all be sent with message to enable recipient 212 * to see complete html message. Location of resources can be given in few 213 * different forms and depending on that, allocation resolving can be successful or 214 * not. Following text represents different possibilities for defining locations 215 * of resources (pictures, animations, sound...) inside of html code passed to 216 * this method, and necessery passed additional parameters used for resolving 217 * this resource locations.<BR> 218 * <BR> 219 * <UL> 220 * <LI>URL defined as: http://... is left unchanged. This resource is not sent 221 * with the message and it couldn't be seen by recipient if it is not online on 222 * the internet.</LI> 223 * <LI>URL defined as: file://... is transformed to corresponding Content ID if 224 * the resource can be found on specified location and it is sent with message.</LI> 225 * <LI>Absolute path, for example defined as: "c:\tmp\test\picture.bmp", is 226 * transformed to corresponding Content ID if the resource can be found on 227 * specified location, and is sent with message. If all resources in html 228 * code are specified with its absolute path, the 3rd parameter in this method 229 * can be null.</LI> 230 * <LI>Relative path of all resources specified in html code, for example 231 * defined as: ".\test\picture.bmp" and ".\example\flush.swf", must be defined 232 * to be relative to same directory path (in this case it is c:\tmp). This parameter 233 * (common directory path) is given as 3rd parameter in this method, and is named 234 * "path". If html code is obtained from .html file, necessery common directory 235 * path is usually path to this .html file. Location of resource is transformed 236 * to corresponding Content ID if the resource can be found on specified location. 237 * This location is sent with the message.</LI> 238 * <LI>Byte array stream as resource for html attribute must be referenced from 239 * html code as: <BR> 240 * <BR><PRE> 241 * *****nnn<virtual_file_name><BR> 242 * <BR></PRE> 243 * Five '*' characters (must be five) define that it is resource expected from 244 * the stream. Other three characters must be digits (000-999) and represent 245 * index of corresponding stream in stream array. virtual_file_name is name and 246 * extension assigned to data passed from stream. Name is used in construction of 247 * "name" parameter in Content-Type, while extension of file name is used in 248 * detection of appropriate mime-type. Lenght of virtual_file_name is not 249 * important. If there is no data referenced from byte array stream ,4th 250 * parameter of this method named "resources" can be null. Also, if all resources 251 * are passed through the array of streams, 3th parameter ("path") can be null. 252 * Location of resource is transformed to corresponding Content ID if no error 253 * has occured during the process of allocation.</LI> 254 * </UL> 255 * <BR> 256 * All mentioned resource allocation types can be combined together in the same 257 * html code, and all will be processed with appropriate use of this method.<BR> 258 * <BR> 259 * Note that number of resource references that are defined in html code by 260 * using virtual_file_names must be greater than or equal to number of elements 261 * in array of InputStream (4th parameter). If one resource (one element in array 262 * of IputStream) is used in html code more than once, it is advisable to use 263 * same virtual_file_name in html code because message is then sent with only 264 * one attached resource (image, movie...). It is essetntial that desired resource 265 * in input stream array corresponds to specified "nnn" part of virtual_file_name.<BR> 266 * <BR> 267 * If resources specified on any described name can not be found or resolved, 268 * or if any exception has occured during its processing, they won't be added and 269 * html message will be sent withouth them. 270 * @param content String representation of message content (text or html code). 271 * @param type type of given content. It can take values: "text/plain" or 272 * "text/html". 273 * @param path common directory path for relative file locations in html code. 274 * It can be null if all resources set absolute path or are defined by 275 * byte array streams, or if sending resources with relative address it is not desired. 276 * Also, it is set to null in case of text/plain message. 277 * @param resources way for representing resources used in the given html code 278 * which will be added to message as array of InputStream. Detail use 279 * of this argument is described above. It can be null if no resources as byte 280 * array stream are used, or if sending resources given in that way is not desired. 281 * Also, it is set to null in case of text/plain message. 282 * @exception SMIMEException if content is tried to be added twice, or in case of 283 * wrong "type" parameter. Also, it can be caused by non SMIMEException which can 284 * be one of the following: MessagingException UnsoportedEncodingException. 285 */ 286 public void setContent(String content, String type, String path, 287 InputStream[] resources) throws SMIMEException { 288 289 if (content != null) { 290 ByteArrayInputStream bais = null; 291 292 try { 293 bais = new ByteArrayInputStream(content.getBytes("ISO-8859-1")); 294 } catch (Exception e) { 295 throw SMIMEException.getInstance(this, e, "setContent"); 296 } 297 this.setContent(bais, type, path, resources); 298 299 } else 300 throw new SMIMEException(this, 1035); 301 } 302 303 /*** 304 * Sets message content from InputStream. This method can be performed only once. 305 * Message content can be given in two differrent forms: text and html code. If 306 * content is type of text, parameter "type" should be "text/plain", while if 307 * content is type of html code, parameter "type" should be set as "html/code". 308 * For further information refer to setContent method with four arguments 309 * (String, String, String, InputStream[] ) which is called by this method. 310 * @param content message content data given from any InputStream. 311 * Data can be text or html code and will be interpreted according to second 312 * parameter: "type". 313 * @param type type of given content. It can take values: "text/plain" or 314 * "text/html". 315 * @param path common directory path for relative file locations in html code. 316 * It can be null if all resources in html code have set absolute path or are 317 * defined by byte array streams, or if sending resources with relative address 318 * is not desired. Also, it is set to null in case of text/plain message. 319 * @param resources way for representing resources used in the given html code 320 * which will be added to message as array of InputStreams. Detail use 321 * of this argument is described in other setContent methods mentioned before. 322 * It can be null if no resources as byte array stream are used, or if sending 323 * resources given in that way is not desired. Also, it is set to null in case 324 * of text/plain message. 325 * @exception SMIMEException if content is tried to be added twice , in case of 326 * wrong "type" parameter or in case when parameter content is null. Also, it can 327 * be caused by non SMIMEException which is MessagingException. 328 */ 329 public void setContent(InputStream content, String type, String path, 330 InputStream[] resources) throws SMIMEException { 331 if (textContentPresence) 332 throw new SMIMEException(this, 1049); 333 if (content != null) { 334 try { 335 if (type.equalsIgnoreCase("text/plain")) { 336 MimeBodyPart mbp = new MimeBodyPart(); 337 String temp = new String(ConvertAssist.inStreamToByteArray(content), "ISO-8859-1"); 338 339 mbp.setText(temp, "ISO-8859-1"); 340 bodyPartArray.add(0, mbp); 341 textContentPresence = true; 342 } else if (type.equalsIgnoreCase("text/html")) { 343 MimeMultipart htmlMultipart = 344 MultipartGenerator.getHtmlMultipart(content, path, resources); 345 346 bodyPartArray.add(0, htmlMultipart); 347 textContentPresence = true; 348 } else 349 throw new SMIMEException(this, 1048); 350 } catch (Exception e) { 351 throw SMIMEException.getInstance(this, e, "setContent"); 352 } 353 } else 354 throw new SMIMEException(this, 1035); 355 } 356 357 /*** 358 * Sets message content from InputStream. This method can be performed only once. 359 * Message content can be given in two differrent forms: text and html code. If 360 * content is type of text, parameter "type" should be "text/plain", while if 361 * content is type of html code, parameter "type" should be set as "html/code". 362 * If html code content is set by this method, message will be generated withouth 363 * inclusion of the resources defined in paricular html element's attribute ("src" and 364 * "background"). Only plain html code will be sent and any reference to local 365 * file system resources will be useless for recipient of the message. HTTP referenced 366 * resources can still be available if recipient is online on Internet. Message 367 * generated on this way is smaller so encrypting process should be faster. 368 * @param content message content data given from any InputStream. 369 * Data could be text or html code and will be interpreted according to second 370 * parameter: "type". 371 * @param type type of given content. It can take values: "text/plain" or 372 * "text/html". 373 * @exception SMIMEException if content is tried to be added twice , in case of 374 * wrong "type" parameter or in case when parameter content is null. Also, it can 375 * be caused by non SMIMEException which is MessagingException. 376 */ 377 public void setContent(InputStream content, String type) throws SMIMEException { 378 if (textContentPresence) 379 throw new SMIMEException(this, 1049); 380 if (content != null) { 381 try { 382 if (type.equalsIgnoreCase("text/plain")) { 383 MimeBodyPart mbp = new MimeBodyPart(); 384 String temp = new String(ConvertAssist.inStreamToByteArray(content), "ISO-8859-1"); 385 386 mbp.setText(temp, "ISO-8859-1"); 387 bodyPartArray.add(0, mbp); 388 textContentPresence = true; 389 } else if (type.equalsIgnoreCase("text/html")) { 390 MimeMultipart htmlMultipart = 391 MultipartGenerator.getHtmlMultipart(content); 392 393 bodyPartArray.add(0, htmlMultipart); 394 textContentPresence = true; 395 } else 396 throw new SMIMEException(this, 1048); 397 } catch (Exception e) { 398 throw SMIMEException.getInstance(this, e, "setContent"); 399 } 400 } else 401 throw new SMIMEException(this, 1035); 402 } 403 404 /*** 405 * Sets message content from String. This method can be performed only once. 406 * Message content can be given in two differrent forms: text and html code. If 407 * content is type of text, parameter "type" should be "text/plain", while if 408 * content is type of html code, parameter "type" should be set as "html/code". 409 * If html code content is set by this method, message will be generated withouth 410 * inclusion of the resources defined in paricular html element's attribute ("src" or 411 * "background"). Only plain html code will be sent and any reference to local 412 * file system resources will be useless for recipient of the message. HTTP referenced 413 * resources can still be available if recipient is online on Internet. Message 414 * generated on this way is smaller, so encrypting process should be faster. 415 * @param content message content data given as String which can 416 * be text or html code and will be interpreted according to second parameter: 417 * "type". 418 * @param type type of given content. It can take values: "text/plain" or 419 * "text/html". 420 * @exception SMIMEException if content is tried to be added twice, or in case of 421 * wrong "type" parameter. Also, it can be caused by non SMIMEException which can 422 * be one of the following: MessagingException UnsoportedEncodingException. 423 */ 424 public void setContent(String content, String type) throws SMIMEException { 425 426 if (content != null) { 427 ByteArrayInputStream bais = null; 428 429 try { 430 bais = new ByteArrayInputStream(content.getBytes("ISO-8859-1")); 431 } catch (Exception e) { 432 throw SMIMEException.getInstance(this, e, "setContent"); 433 } 434 this.setContent(bais, type); 435 436 } else 437 throw new SMIMEException(this, 1035); 438 } 439 440 /*** 441 * Sets message content from file represented by File object. This method can be 442 * performed only once. Message content can be given in two differrent forms: 443 * text and html code. If content is type of text, parameter "type" should be 444 * "text/plain", while if content is type of html code, parameter "type" should 445 * be set as "html/code". For further information refer to setContent method 446 * with four arguments (String, String, String, InputStream[] ) which is called 447 * by this method. 448 * @param inFile location of file which is used for content of the message 449 * @param type type of given content. It can take values: "text/plain" or 450 * "text/html". 451 * @exception SMIMEException if content is tried to be added twice, in case of 452 * wrong "type" parameter, or if passed file (as File object) does not exist in 453 * file sistem. Also, it can be caused by non SMIMEException which can be one of 454 * the following: MessagingException or IOException. 455 */ 456 public void setContent(File inFile, String type) throws SMIMEException { 457 458 if (textContentPresence) 459 throw new SMIMEException(this, 1049); 460 if (inFile != null && inFile.exists()) { 461 try { 462 File inFileAbs = inFile.getAbsoluteFile().getCanonicalFile(); 463 String content = ConvertAssist.readFileToString(inFileAbs); 464 465 this.setContent(content, type, inFile.getParent(), null); 466 } catch (Exception e) { 467 throw SMIMEException.getInstance(this, e, "setContent"); 468 } 469 } else 470 throw new SMIMEException(this, 1034); 471 } 472 473 /*** 474 * Sets REPLY TO field in message header 475 * @param replyAddress email address used to reply 476 * @exception SMIMEException caused by non SMIMEException which is 477 * MessagingException. Also, javax.mail.internet.AddressException is thrown 478 * from instances of InternetAddress class (but AddressException extends 479 * MessagingException). 480 */ 481 public void setReply(String replyAddress) throws SMIMEException { 482 try { 483 InternetAddress reply[] = new InternetAddress[1]; 484 485 reply[0] = new InternetAddress(replyAddress); 486 message.setReplyTo(reply); 487 } catch (Exception e) { 488 throw SMIMEException.getInstance(this, e, "addRecipient"); 489 } 490 } 491 492 /*** 493 * Adds recipient address, type and .cer file of email recipient to encrypted 494 * message. 495 * @param recipientAddress email address of recipent (fields TO or CC or BCC 496 * in email message header) 497 * @param type should be TO, CC or BCC 498 * @param cerFileName path and file name with certificate corresponding 499 * to recipient (file with .cer extension) 500 * @exception SMIMEException if type of addressing of messages is not TO, CC 501 * or BCC. 502 * @exception SMIMEException caused by non SMIMEException which is 503 * MessagingException. 504 */ 505 public void addRecipient(String recipientAddress, String type, String cerFileName) 506 throws SMIMEException { 507 try { 508 if (!type.equalsIgnoreCase("TO") & !type.equalsIgnoreCase("BCC") & !type.equalsIgnoreCase("CC")) 509 throw new SMIMEException(this, 1042); 510 if (type.equalsIgnoreCase("TO")) { 511 message.addRecipients(Message.RecipientType.TO, recipientAddress); 512 indicatorTo = true; 513 } else if (type.equalsIgnoreCase("CC")) 514 message.addRecipients(Message.RecipientType.CC, recipientAddress); 515 else if (type.equalsIgnoreCase("BCC")) 516 message.addRecipients(Message.RecipientType.BCC, recipientAddress); 517 } catch (Exception e) { 518 throw SMIMEException.getInstance(this, e, "addRecipient"); 519 } 520 certArray.addElement(cerFileName); // adding location of .cer file in stack 521 } 522 523 /*** 524 * Adds file as attachment to email message 525 * @param fileName path and file name used for attachment 526 * @exception SMIMEException if passed file (as File object) does not exist in 527 * file sistem. Also, it can be caused by non SMIMEException which is 528 * MessagingException 529 */ 530 public void addAttachment(String fileName) throws SMIMEException { 531 File fn = new File(fileName); 532 533 this.addAttachment(fn); 534 } 535 536 /*** 537 * Adds file as attachment to email message 538 * @param file used for attachment represented as File object 539 * @exception SMIMEException if passed file (as File object) does not exist in 540 * file sistem. Also, it can be caused by non SMIMEException which is 541 * MessagingException 542 */ 543 public void addAttachment(File file) throws SMIMEException { 544 if (!file.exists()) 545 throw new SMIMEException(this, 1034); 546 MimeBodyPart attachment = new MimeBodyPart(); 547 FileDataSource fd = new FileDataSource(file); 548 549 try { 550 attachment.setDataHandler(new DataHandler(fd)); 551 attachment.setDisposition(attachment.ATTACHMENT); 552 attachment.setFileName(file.getName()); 553 } catch (Exception e) { 554 throw SMIMEException.getInstance(this, e, "addAttachment"); 555 } 556 557 bodyPartArray.addElement(attachment); 558 } 559 560 /*** 561 * Adds data from InputStream as attachment to email message 562 * @param data byte array from InputStream 563 * @param fileName virtual or real file name (wihouth path). Correct information 564 * about name; extension of file name is especially important. Name 565 * is used in construction of "name" parameter in Content-Type header line of 566 * body parts of mime message. Extension of file is used in detection of 567 * appropriate mime-type. 568 * @exception SMIMEException caused by non SMIMEException which is 569 * MessagingException 570 */ 571 public void addAttachment(InputStream data, String fileName) throws SMIMEException { 572 MimeBodyPart attachment = new MimeBodyPart(); 573 574 try { 575 attachment.setDataHandler(new DataHandler(new StreamDataSource(data, fileName))); 576 attachment.setDisposition(attachment.ATTACHMENT); 577 attachment.setFileName(fileName); 578 bodyPartArray.addElement(attachment); 579 } catch (Exception e) { 580 throw SMIMEException.getInstance(this, e, "addAttachment"); 581 } 582 } 583 584 /*** 585 * Envelopes message with default algorithm RC2_CBC, 40 bits 586 * @exception SMIMEException if one of recipients is not declared as TO 587 * recipient, or if there is no message for enveloping. Also, it can be caused 588 * by non SMIMEException which can be one of the following: CertificateException, 589 * IOException, MessagingException or FileNotFoundException. 590 */ 591 public void enveloping() throws SMIMEException { 592 this.enveloping("RC2_CBC", 40); 593 } 594 595 /*** 596 * Envelopes message with given algorithm name and key length 597 * @param algorithmName name of chosen algorithm used for encryption 598 * @param keyLength key size in bits 599 * @exception SMIMEException if one of recipients is not declared as TO 600 * recipient, or if there is no message for enveloping. Also, it can be caused 601 * by non SMIMEException which can be one of the following: CertificateException, 602 * IOException, MessagingException or FileNotFoundException. 603 */ 604 public void enveloping(String algorithmName, int keyLength) throws SMIMEException { 605 try { 606 if (indicatorTo != true) 607 throw new SMIMEException(this, 1043); 608 if (textContentPresence & bodyPartArray.size() == 1) { // message contains only content 609 if (bodyPartArray.elementAt(0) instanceof MimeBodyPart) { // text/plain message 610 MimeBodyPart contentBody = (MimeBodyPart) bodyPartArray.elementAt(0); 611 612 message.setContent((String) contentBody.getContent(), contentBody.getContentType()); 613 message.setDisposition(message.INLINE); 614 } else // text/html message 615 message.setContent((MimeMultipart) bodyPartArray.elementAt(0)); 616 } else if (bodyPartArray.size() != 0) { 617 Multipart mp = new MimeMultipart(); 618 619 for (int i = 0; i != bodyPartArray.size(); i++) { 620 if (bodyPartArray.elementAt(i) instanceof MimeMultipart) { 621 MimeBodyPart forMulti = new MimeBodyPart(); 622 623 forMulti.setContent((MimeMultipart) bodyPartArray.elementAt(i)); 624 mp.addBodyPart(forMulti); 625 } else 626 mp.addBodyPart((MimeBodyPart) bodyPartArray.elementAt(i)); 627 } 628 message.setContent(mp); 629 } else 630 throw new SMIMEException(this, 1044); 631 632 CMSEnvelopedDataSource es = new CMSEnvelopedDataSource(message, algorithmName, keyLength); 633 634 for (int i = 0; i != certArray.size(); i++) { 635 InputStream inStream = new FileInputStream((String) (certArray.elementAt(i))); 636 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 637 X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream); 638 639 inStream.close(); 640 es.addRecipient(cert); 641 } 642 643 message.setDataHandler(new DataHandler(es)); 644 HeadersUtil.updateHeaders(message); 645 message.setDescription("Enveloped SMIME message."); 646 message.setDisposition(message.ATTACHMENT); 647 SimpleTimeZone tz = (SimpleTimeZone) SimpleTimeZone.getDefault(); // Sets date and time 648 GregorianCalendar cal = new GregorianCalendar(tz); 649 650 message.setSentDate(cal.getTime()); 651 652 clean(); 653 } catch (Exception e) { 654 throw SMIMEException.getInstance(this, e, "enveloping"); 655 } 656 } 657 658 /*** 659 * Returns SMIME Message 660 * @return Enveloped S/MIME message 661 */ 662 public MimeMessage getEnvelopedMessage() { 663 return message; 664 } 665 666 /*** 667 * Sends S/MIME message to SMTP host 668 * @exception MessagingException caused by use of methods from objects of class 669 * Transport. 670 */ 671 public void send() throws MessagingException { 672 Transport.send(message); 673 } 674 675 /*** 676 * Releases unnecessary memory 677 */ 678 private void clean() { 679 bodyPartArray = null; 680 certArray = null; 681 System.gc(); // Calling garbage collector 682 } 683 684 } 685

This page was automatically generated by Maven